package Presentation;

import Metier.Controleurs.GestionParamProduit;
import Metier.Controleurs.GestionStock;
import Metier.Objets.Produit;
import Metier.Objets.TypeProduit;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableModel;

/**
 * Onglet de gestion des stocks
 */
public final class OngletStock extends Onglet {

    /**
     * Attributs
     */
    // Contrôleur de la gestion des stocks
    private final GestionStock gStock;
    private final ResourceBundle configBundle;
    
    private JScrollPane scrollTblGeneral;
    private JScrollPane scrollTblSupprBoisson;
    
    private JTable tblGeneral;
    private JTable tblSupprBoisson;
    
    private JPanel panelPopupVariation;
    private JPanel panelSpinner;
    private JPanel panelDatePeremption;
    private JPanel panelPopupSupprBoisson;
            
    private JLabel labelTypeProduit;
    private JLabel labelValeurActuelle;
    private JLabel labelChampModif;
    private JLabel labelChampDate;
    
    private JSpinner spinnerAjoutLibelleProduit;
    
    private SelecteurDate SelectDatePeremption;
    
    private final OngletStock that;
    
    private LabelColumn lblColumn;

    /**
     * Constructeur OngletStock
     * @param fp la fenetre parente / principale
     */
    public OngletStock(FenetrePrincipale fp) {
            super(fp);
            this.that = this;
            this.gStock = new GestionStock(this);
            this.configBundle = ResourceBundle.getBundle("ressources/Stocks/Stocks", fp.getLocale());

            initComponents();
    }

    /**
     * Initialisation des composants graphiques de l'onglet
     */
    private void initComponents() {
        // JTable des stocks, contenu importé par gStock
        this.tblGeneral = new JTable(this.gStock.getContenuTableauGeneral()){
            @Override
            public boolean isCellEditable(int row, int column){
                return column >= 2;
            }
        };
        this.tblGeneral.setRowHeight(20);
        //on cache la colonne contenant les id
        this.tblGeneral.removeColumn(this.tblGeneral.getColumnModel().getColumn(4));
        //on centre le texte dans les cellules
        DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
        centerRenderer.setHorizontalAlignment( JLabel.CENTER );
        tblGeneral.setDefaultRenderer(Object.class, centerRenderer);
        
        this.scrollTblGeneral = new JScrollPane(this.tblGeneral);
        this.add(this.scrollTblGeneral, BorderLayout.CENTER);

        //On ajoute les boutons Ajouter et Supprimer dans les 2 dernières colonnes visibles
        gStock.rafraichirAlertes();
        initButtonColumn();
        initLabelColumn();
        setRedLabels();
        
        //Composants du pop-up d'ajout ou de retrait d'un lot
        this.panelPopupVariation = new JPanel(new GridLayout(4,1));
        this.panelSpinner = new JPanel(new GridLayout(1,2));
        this.panelDatePeremption = new JPanel(new GridLayout(1,2));
        this.panelPopupSupprBoisson = new JPanel(new GridLayout(1,1));
        
        this.labelTypeProduit = new JLabel("");
        this.labelValeurActuelle = new JLabel("");
        this.labelChampModif = new JLabel("");
        
        SpinnerModel model = new SpinnerNumberModel(0, 0, null, 1);
        this.spinnerAjoutLibelleProduit = new JSpinner(model);
        
        //JTable qui liste les lots de boissons. Contenu importé au clic sur le bouton puisqu'il doit s'adapter au produit choisi
        this.tblSupprBoisson = new JTable(){
                @Override
                public boolean isCellEditable(int row, int column){
                    return column >= 3;
                }
            };
        this.tblSupprBoisson.setRowHeight(30);
        //on centre le texte dans les cellules
        tblSupprBoisson.setDefaultRenderer(Object.class, centerRenderer);
        
        this.scrollTblSupprBoisson = new JScrollPane(this.tblSupprBoisson);
        this.labelChampDate = new JLabel(configBundle.getString("stock.datePeremption"));
        this.SelectDatePeremption = new SelecteurDate();
        
        //Attachement des composants des popups
        this.panelSpinner.add(labelChampModif);
        this.panelSpinner.add(spinnerAjoutLibelleProduit);
        
        this.panelDatePeremption.add(labelChampDate);
        this.panelDatePeremption.add(SelectDatePeremption);
        
        this.panelPopupVariation.add(labelTypeProduit);
        this.panelPopupVariation.add(labelValeurActuelle);
        this.panelPopupVariation.add(panelSpinner);
        this.panelPopupVariation.add(panelDatePeremption);
        
        this.panelPopupSupprBoisson.add(scrollTblSupprBoisson, BorderLayout.CENTER);
        
        javax.swing.Timer timerAlertes = new javax.swing.Timer(5000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ThreadRafraichissementStock thread = new ThreadRafraichissementStock(that, gStock);
                thread.start();
            }
        });
        timerAlertes.start();
    }

    /**
     * raflaichit le contenu de la table principale
     */
    @Override
    public void rafraichir() {
        TableModel tm = gStock.getContenuTableauGeneral();
        this.tblGeneral.removeAll();
        this.tblGeneral.setModel(tm);
        this.tblGeneral.removeColumn(this.tblGeneral.getColumnModel().getColumn(4));
        gStock.rafraichirAlertes();
        initButtonColumn();
        initLabelColumn();
        setRedLabels();
        this.tblGeneral.repaint();
    }

    /**
     * Affiche un popup d'aide
     */
    @Override
    public void help() {
        JOptionPane.showMessageDialog(this.getFP(),
                configBundle.getString("stock.txtAide"),
                configBundle.getString("stock.aide"),
                JOptionPane.INFORMATION_MESSAGE);
    }
    
    /**
     * Cette fonction rend rouge le nom des produits en alerte stock
     */
    public void setRedLabels(){
        int nbProduits = this.tblGeneral.getRowCount();
        for(int i=0; i<nbProduits; i++){
            ((JLabel)(this.lblColumn.getValue(i))).setForeground(Color.BLACK);
            String nom = ((JLabel)(this.lblColumn.getValue(i))).getText();
            for(Produit p : gStock.getListeAlertes()){
                if(p.getNom().equals(nom)){
                    ((JLabel)(this.lblColumn.getValue(i))).setForeground(Color.RED);
                }
            }
        }
    }

    /**
     * Initialisation des boutons Ajouter et Supprimer dans la table principale
     */
    private void initButtonColumn(){
        // Action lors du clic sur le bouton "Ajouter" d'une ligne de produit
        Action ajoutLot = new AbstractAction(){
            @Override
            public void actionPerformed(ActionEvent e){
                //Récupération du produit à éditer
                int row = ((JTable)e.getSource()).getSelectedRow();
                Produit stockAjout = new GestionParamProduit().getProduit(Integer.valueOf(tblGeneral.getModel().getValueAt(row, 4).toString()));
                
                //Affichage du popup d'ajout
                afficherPopupAjoutLot(stockAjout);
            }
        };

        // Action lors du clic sur le bouton "Supprimer" d'une ligne de produit
        Action supprLot = new AbstractAction(){
            @Override
            public void actionPerformed(ActionEvent e){
                //Récupération du produit à éditer
                int row = ((JTable)e.getSource()).getSelectedRow();
                Produit stockSuppr = new GestionParamProduit().getProduit(Integer.valueOf(tblGeneral.getModel().getValueAt(row, 4).toString()));
                
                //Affichage du popup de suppression
                afficherPopupSupprLot(stockSuppr);
            }
        };

        // Ajout de la colonne des boutons "Ajouter" produit
        new ButtonColumn(tblGeneral, ajoutLot, 2);
        // Ajout de la colonne des boutons "Supprimer" produit
        new ButtonColumn(tblGeneral, supprLot, 3);
    }
    
    /**
     * Affiche la popup d'ajout d'un produit et effectue les modifications si le bouton OK est cliqué
     * @param aAjouter type de produit a ajouter
     */
    public void afficherPopupAjoutLot(Produit aAjouter){
        //initialisation de l'interface
        this.labelTypeProduit.setText(configBundle.getString("stock.txtAjoutLot")+" "+aAjouter.getNom());
        this.labelValeurActuelle.setText(configBundle.getString("stock.stockActuel")+" "+gStock.sommeQuantites(gStock.getStock(aAjouter)));
        this.labelChampModif.setText(configBundle.getString("stock.ajouterCombien"));
        this.spinnerAjoutLibelleProduit.setValue(0);
        final boolean estBoisson = aAjouter.getType() == TypeProduit.BOISSON;
        if(estBoisson){
            this.SelectDatePeremption.setEnabled(true);
        }
        else{
            this.SelectDatePeremption.setEnabled(false);
        }
        
        int qte;
        //Affichage du popup
        int choice = JOptionPane.showConfirmDialog(getFP(), this.panelPopupVariation, configBundle.getString("stock.addLot"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
        if(choice == JOptionPane.OK_OPTION){
            qte = (Integer)this.spinnerAjoutLibelleProduit.getValue();
            if(estBoisson){ // on gère en plus la date de péremption
                gStock.ajouterAuStock(aAjouter, qte, SelectDatePeremption.getFormatedDate());
            }
            else{
                if(qte != 0){
                    gStock.ajouterAuStock(aAjouter, qte);
                }
            }
            if(qte != 0){
                rafraichir();
            }
        }
    }
    
    /**
     * Affiche la popup de suppression d'un produit et effectue les modifications si le bouton OK est cliqué
     * @param aSupprimer le type de produit à supprimer
     */
    public void afficherPopupSupprLot(Produit aSupprimer){
        int qte;
        if(aSupprimer.getType() == TypeProduit.VIENNOISERIE){
            //initialisation de l'interface
            this.panelDatePeremption.setVisible(false);
            this.labelTypeProduit.setText(configBundle.getString("stock.txtSupprLot")+" "+aSupprimer.getNom());
            this.labelValeurActuelle.setText(configBundle.getString("stock.stockActuel")+" "+gStock.getStock(aSupprimer).get(0).getQuantite());
            this.labelChampModif.setText(configBundle.getString("stock.supprCombien"));
            this.panelDatePeremption.add(SelectDatePeremption);
            this.spinnerAjoutLibelleProduit.setValue(0);
            this.SelectDatePeremption.setEnabled(false);
            
            //Affichage du popup
            int choice = JOptionPane.showConfirmDialog(getFP(), this.panelPopupVariation, configBundle.getString("stock.supprVienn"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
            if(choice == JOptionPane.OK_OPTION){
                qte = (Integer)this.spinnerAjoutLibelleProduit.getValue();
                if(qte !=0){
                    gStock.retirerAuStock(aSupprimer, qte);
                    rafraichir();
                }
            }
            
            this.panelDatePeremption.setVisible(true);
        }
        else{
            //initialisation de la JTable, contenu importé depuis gStock
            this.tblSupprBoisson.setModel(this.gStock.getContenuTableauSupprBoisson(aSupprimer));
            //Ajout des JSpinners de choix du nombre
            SpinnerColumn spC = new SpinnerColumn(this.tblSupprBoisson, 3);
            //masquage de la colonne des id
            this.tblSupprBoisson.removeColumn(this.tblSupprBoisson.getColumnModel().getColumn(4));
            
            //Affichage du popup
            int choice = JOptionPane.showConfirmDialog(getFP(), this.panelPopupSupprBoisson, configBundle.getString("stock.supprBoissons"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
            if(choice == JOptionPane.OK_OPTION){
                //map qui relie un id de stock à la quantité à supprimer dans ce stock
                Map<Integer, Integer> mapSupprBoisson = new HashMap<>();
                qte = 0;
                for(int i = 0; i<this.tblSupprBoisson.getRowCount();i++){
                    if((int)spC.getValue(i) != 0){
                        qte = (int)spC.getValue(i);
                        mapSupprBoisson.put((Integer.valueOf(tblSupprBoisson.getModel().getValueAt(i, 4).toString())), qte);
                    }
                    else{
                        mapSupprBoisson.put((Integer.valueOf(tblSupprBoisson.getModel().getValueAt(i, 4).toString())), 0);
                    }
                }
                gStock.retirerAuStock(mapSupprBoisson);
                if(qte != 0){
                    rafraichir();
                }
            }
        }
    }

    /**
     * Initialise les JLabel de la colonne 0
     */
    private void initLabelColumn() {
        this.lblColumn = new LabelColumn(this.tblGeneral,0);
    }
}
